package com.edfu.core.commons.service.ws;

import java.io.IOException;
import java.io.InputStream;
import java.util.List;

import javax.activation.DataHandler;
import javax.jws.WebMethod;
import javax.jws.WebService;
import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.Consumes;
import javax.ws.rs.GET;
import javax.ws.rs.POST;
import javax.ws.rs.Path;
import javax.ws.rs.PathParam;
import javax.ws.rs.Produces;
import javax.ws.rs.core.Context;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.MultivaluedMap;
import javax.ws.rs.core.Response;
import javax.ws.rs.core.Response.ResponseBuilder;

import org.apache.commons.io.IOUtils;
import org.apache.cxf.jaxrs.ext.multipart.Attachment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;

import com.edfu.core.commons.beans.EduObjectType;
import com.edfu.core.commons.service.api.IResourceMgtService;
import com.edfu.core.testmgt.vo.Resource;

@Path("/")
@Produces( { MediaType.APPLICATION_JSON })
@Consumes(MediaType.APPLICATION_XML)
@WebService(targetNamespace = "http://com.edfu.core.commons.service.ws.ResourceMgtService")
public class ResourceMgtServiceDelegate {
	
	private static Logger logger = LoggerFactory.getLogger(ResourceMgtServiceDelegate.class);
	
	@Autowired
	private IResourceMgtService resourceMgtService;
	
	/*@POST
	@Path("/resources")
	@WebMethod(operationName = "uploadResource")
	public Response uploadResource(Resource resource) {
		logger.info("Uploading Resource " + resource.getName());
		resourceMgtService.uploadResource(resource);		
		
		return Response.ok().build();
		
	}*/
	
	@POST
	@Path("/resources")
	@Consumes(MediaType.MULTIPART_FORM_DATA)
	@WebMethod(operationName = "uploadResource")
	public Response uploadResource(List<Attachment> attachments, @Context HttpServletRequest request) {
		for (Attachment attachment : attachments) {
	         DataHandler handler = attachment.getDataHandler();
	         try {
	            InputStream stream = handler.getInputStream();
	            MultivaluedMap<String, String> map = attachment.getHeaders();
	            
	            Resource resource = new Resource();
//	            resource.setContentType(getContentType(map));
	            resource.setType(getContentType(map));
	            resource.setName(getFileName(map));
	            resource.setInputStream(stream);
	            
	            resourceMgtService.uploadResource(resource);
	            
	         } catch (Exception e) {
	            logger.warn(e.getMessage());
	            return Response.serverError().build();
	         }
	      }
		return Response.ok().build();
		
	}
	
	private String getFileName(MultivaluedMap<String, String> header) {
	      String[] contentDisposition = header.getFirst("Content-Disposition").split(";");
	      for (String filename : contentDisposition) {
	         if ((filename.trim().startsWith("filename"))) {
	            String[] name = filename.split("=");
	            String exactFileName = name[1].trim().replaceAll("\"", "");
	            return exactFileName;
	         }
	      }
	      return "unknown";
	   }
	
	private String getContentType(MultivaluedMap<String, String> header) {
		return header.get("Content-Type").get(0);		
	}
	
	@GET
	@Path("/resources/{uuid}")
	@WebMethod(operationName = "getResource")
    public Response getResource(@PathParam(value = "uuid") String uuid) throws IOException {
    	logger.info("Getting resource for the UUID " + uuid);    	
    	Resource resource = resourceMgtService.getResource(uuid);
    	ResponseBuilder response = Response.ok(IOUtils.toByteArray(resource.getInputStream()));
    	
        response.header("Content-Disposition", "attachment; filename="+resource.getName()+"; description=" + resource.getDescription()+"; contentType=" + resource.getContentType()+"; type=" + resource.getType() ); 
    	return response.build();
    }
    
	@POST
	@Path("/resources/id/{id}/objectId/{objectId}/objectType/{objectType}")
	@WebMethod(operationName = "mapResource")
    public Response mapResource(@PathParam(value = "id") long id, @PathParam(value = "objectId") long objectId, @PathParam(value = "objectType") String objectType) {
    	resourceMgtService.mapResource(id, objectId, EduObjectType.valueOf(objectType));
    	
    	return Response.ok().build();
    }
	
	@GET
	@Path("/resources/objectId/{objectId}/objectType/{objectType}")
	@WebMethod(operationName = "getResources")
	public List<Resource> getResources(@PathParam(value = "objectId") long objectId, @PathParam(value = "objectType") String objectType) {
		return resourceMgtService.getResources(objectId, EduObjectType.valueOf(objectType));
	}	
	
}
